//package me.seawenc.db.checker.service;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import me.seawenc.db.checker.dbengine.DsType;
//import me.seawenc.db.checker.dbengine.IEngineService;
//import me.seawenc.db.checker.dbengine.impl.engines.bean.TableColumnBean;
//import me.seawenc.db.checker.dbengine.impl.engines.bean.TableDetailBean;
//import me.seawenc.db.checker.dbengine.impl.engines.bean.TableNameBean;
//import me.seawenc.db.checker.bean.FileConfig;
//import me.seawenc.db.checker.bean.ExecParameters;
//import me.seawenc.db.checker.bean.CheckMetaBean;
//import me.seawenc.db.checker.helper.FileHelper;
//import me.seawenc.db.checker.helper.Log;
//import me.seawenc.db.checker.helper.Optionalx;
//
//import java.util.*;
//import java.util.stream.Collectors;
//
//public class SchemaService {
//
//    /**
//     * 元数据导出
//     * @param parameters
//     */
//    public static void export(ExecParameters parameters) {
//        try {
//            // 生成元数据对象
//            CheckMetaBean checkMeta = createCheckMeta(parameters);
//            // 导出元数据到文件
//            FileHelper.writeToFile(parameters, JSON.toJSONString(checkMeta));
//            Log.info("0.从数据库中获得表总数为：%s,配置表数为：%s",checkMeta.getTableMetaMap().size(),checkMeta.getConfTableItemMap().size());
//            Log.info("1.元数据对象生成成功，当前数据库版本:%s,元数据文件路径：%s",checkMeta.getDbVersion(),parameters.getCheckPath());
//        } catch (Exception e) {
//            Log.error(e.getMessage(),e);
//            throw new RuntimeException(e.getMessage());
//        }
//    }
//
//    /**
//     * 对比元数据
//     * @param parameters
//     */
//    public static void check(ExecParameters parameters) {
//        try {
//            // 生成元数据对象
//            CheckMetaBean target = createCheckMeta(parameters);
//            // 读取元数据json文件
//            CheckMetaBean src=readFromFile(parameters.getCheckPath());
//            // 对比两个元数据，打印出差异
//            diffMetaAndPrint(target,src);
//        } catch (Exception e) {
//            Log.error(e.getMessage(),e);
//            throw new RuntimeException(e.getMessage());
//        }
//    }
//
//    private static CheckMetaBean readFromFile(String checkPath) throws Exception {
//        String metaStr = FileHelper.readExtFile(checkPath).stream().collect(Collectors.joining("\n"));
//        CheckMetaBean meta = JSONObject.parseObject(metaStr, CheckMetaBean.class);
//        return meta;
//    }
//
//    private static void diffMetaAndPrint(CheckMetaBean target, CheckMetaBean src) {
//        Log.info("0.从`数据库/json文件`中获得表总数为：`%s/%s`,配置表数为：`%s/%s`",target.getTableMetaMap().size(),src.getTableMetaMap().size(),target.getConfTableItemMap().size(),src.getConfTableItemMap().size());
//        Log.info("1.目标库版本:%s,json文件中的数据库版本：%s,json文件生成时间：%s",target.getDbVersion(),src.getDbVersion(),src.getDatetime());
//        Log.info("2.schema元数据对比结果：（若无日志，则表示完全一致）=================================");
//        diffTableMeta(target, src);
//        Log.info("3.conf表配置项对比结果：（若无日志，则表示完全一致）=================================");
//        diffConf(target, src);
//        Log.info("4.检查结束================================================================");
//    }
//
//    private static void diffConf(CheckMetaBean target, CheckMetaBean src) {
//        {// 检查配置表是否一致
//            Set<String> targetConfKeys = target.getConfTableItemMap().keySet();
//            Set<String> srcConfKeys = src.getConfTableItemMap().keySet();
//            String srcNotExist = targetConfKeys.stream().filter(tablename -> !srcConfKeys.contains(tablename)).collect(Collectors.joining(","));
//            String targetNotExist = srcConfKeys.stream().filter(tablename -> !targetConfKeys.contains(tablename)).collect(Collectors.joining(","));
//            //打印出找出的差异
//            Log.condWarn(Optionalx.isPresent(srcNotExist),String.format("conf table=%s，配置表比对：目标库中已配置，生成json文件时未配置",srcNotExist));
//            Log.condWarn(Optionalx.isPresent(targetNotExist),String.format("conf table=%s，配置表比对：目标库中未配置，生成json文件时已配置",targetNotExist));
//        }
//
//        // 检查各表的配置项是否一致
//        for(Map.Entry<String, List<String>> targetEntry: target.getConfTableItemMap().entrySet()){
//            List<String> srcTableInfo = src.getConfTableItemMap().get(targetEntry.getKey());
//            if(Optionalx.isNotPresent(srcTableInfo)){
//                //此种情况已经检查过了
//                continue;
//            }
//            String srcNotExist = targetEntry.getValue().stream().filter(name -> !srcTableInfo.contains(name)).collect(Collectors.joining(","));
//            String targetNotExist = srcTableInfo.stream().filter(name -> !targetEntry.getValue().contains(name)).collect(Collectors.joining(","));
//            // 打印出找出的差异
//            Log.condWarn(Optionalx.isPresent(srcNotExist),String.format("conf table=%s，值对比：目标库中存在，json文件中不存在的字段有：%s",targetEntry.getKey(),srcNotExist));
//            Log.condWarn(Optionalx.isPresent(targetNotExist),String.format("conf table=%s，值对比：json文件中存在，目标库中不存在的字段有：%s",targetEntry.getKey(),targetNotExist));
//        }
//    }
//
//    private static void diffTableMeta(CheckMetaBean target, CheckMetaBean src) {
//        {// 检查表数量是否一致，打印出差异
//            Set<String> targetConfKeys = target.getTableMetaMap().keySet();
//            Set<String> srcConfKeys = src.getTableMetaMap().keySet();
//            String srcNotExist = targetConfKeys.stream().filter(tablename -> !srcConfKeys.contains(tablename)).collect(Collectors.joining(","));
//            String targetNotExist = srcConfKeys.stream().filter(tablename -> !targetConfKeys.contains(tablename)).collect(Collectors.joining(","));
//            //打印出找出的差异
//            Log.condWarn(Optionalx.isPresent(srcNotExist),String.format("表比对：目标库中存在，json文件中不存在的表有：%s",srcNotExist));
//            Log.condWarn(Optionalx.isPresent(targetNotExist),String.format("表比对：json文件中存在，目标库中不存在的表有：%s",targetNotExist));
//        }
//
//        // 检查各表的字段项是否一致
//        for(Map.Entry<String, List<TableColumnBean>> targetEntry: target.getTableMetaMap().entrySet()){
//            List<TableColumnBean> srcTableInfo = src.getTableMetaMap().get(targetEntry.getKey());
//            if(Optionalx.isNotPresent(srcTableInfo)){
//                //此种情况已经检查过了
//                continue;
//            }
//            List<String> srcColumnNames = srcTableInfo.stream().map(i -> i.getColumnName()).collect(Collectors.toList());
//            List<String> targetColumnNames = targetEntry.getValue().stream().map(i -> i.getColumnName()).collect(Collectors.toList());
//
//            String srcNotExist = targetColumnNames.stream().filter(name -> !srcColumnNames.contains(name)).collect(Collectors.joining(","));
//            String targetNotExist = srcColumnNames.stream().filter(name -> !targetColumnNames.contains(name)).collect(Collectors.joining(","));
//            // 打印出找出的差异
//            Log.condWarn(Optionalx.isPresent(srcNotExist),String.format("table=%s,字段比对：目标库中存在，json文件中不存在的字段有：%s",targetEntry.getKey(),srcNotExist));
//            Log.condWarn(Optionalx.isPresent(targetNotExist),String.format("table=%s,字段比对：json文件中存在，目标库中不存在的字段有：%s",targetEntry.getKey(),targetNotExist));
//        }
//    }
//
//    private static CheckMetaBean createCheckMeta(ExecParameters parameters) throws Exception {
//        FileConfig fileConfig = createFileParameters(parameters.getConfigPath());
//        IEngineService dbEngine = DsType.findDbEngine(fileConfig);
//        CheckMetaBean checkMetaBean=new CheckMetaBean();
//        checkMetaBean.setDbVersion(dbEngine.findVersion());
//        buildTableMeta(dbEngine, checkMetaBean);
//        buildConfItem(dbEngine, checkMetaBean,fileConfig.getConfTableCheckSqls());
//        dbEngine.closeDbCollection();
//
//        return checkMetaBean;
//    }
//
//    private static void buildConfItem(IEngineService dbEngine, CheckMetaBean meta, Map<String,String> sqls) {
//        for(Map.Entry<String,String> entry:sqls.entrySet()){
//            try {
//                Set<String> items = dbEngine.execSelectSql(entry.getValue()).stream().map(row->row.getString("item")).collect(Collectors.toSet());
//                meta.getConfTableItemMap().computeIfAbsent(entry.getKey(),(name)-> new ArrayList<>()).addAll(items);
//            } catch (Exception e) {
//                Log.error("执行配置文件配置项检查sql失败，%s,sql=%s",entry.getKey(),entry.getValue());
//            }
//        }
//    }
//
//    private static void buildTableMeta(IEngineService dbEngine, CheckMetaBean checkMetaBean) throws Exception {
//        List<TableNameBean> allTables = dbEngine.findAllTables();
//        for(TableNameBean tableNameBean:allTables){
//            TableDetailBean tableDetail = dbEngine.findTableDetail(tableNameBean.getTableName());
//            checkMetaBean.getTableMetaMap().computeIfAbsent(tableNameBean.getTableName(),(name)->new ArrayList<>()).addAll(tableDetail.getTableColumns());
//        }
//    }
//
//    private static FileConfig createFileParameters(String filePath) throws Exception {
//        Properties props = FileHelper.readExtResFile(filePath);
//        return FileConfig.getInstance(props);
//    }
//}
